package cyc.learn.mode.singleton.lazy;

/**
 * 单例模式：懒汉式
 * 时间换取空间：加载时不做任何处理，节约空间，使用时再去判断是否存在，没有就创建一个出来，有就直接用
 */
public class Singleton {

    private volatile static Singleton instance = null;

    private Singleton() {}

    /**
     * 获取单例实例
     * 该方法返回的单例可能不是单例
     * @return 单例
     */
    /*public static Singleton getInstance() {
        if (instance == null) {
            System.out.println("new Singleton()");
            instance = new Singleton();
        }
        return instance;
    }*/

    /**
     * 获取单例实例
     * 解决方案1：synchronized
     * 使用sync同步，保证同一时间只能有一个线程进行访问。就保证了只能生成一个实例，这样就保证了单例
     * 问题：sync虽然保证了单例，但是同一时间只能有一个线程进行获取，大大的降低了访问效率
     * @return
     */
    /*public static synchronized Singleton getInstance() {
        if (instance == null) {
            System.out.println("生成一个实例");
            instance = new Singleton();
        }
        return instance;
    }*/

    /**
     * 解决方案2：双重检查加锁
     * 问题分析：首先，我们只需要保证生成的instance只有一个，那么我们sync的代码应该只有new singleton()这里
     * 所以，可以将代码优化如下
     * 此时，代码的效率比之前有了明显提升
     * todo but:经过实际测试，和我预期的不太一样。并没有明显提升。有路过的大佬求指教
     * @return
     */
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}
